import React, { useRef, useEffect, useState } from 'react';
import './MessageBubble.css';
import { useTheme } from '../theme';

/**
 * 消息气泡组件
 * 用于在聊天界面中显示用户和机器人的消息
 * 
 * @param {Object} props - 组件属性
 * @param {Object} props.message - 消息对象
 * @param {string} props.message.text - 消息内容
 * @param {boolean} props.message.isUser - 是否为用户消息
 * @param {string} props.message.timestamp - 消息时间戳
 * @returns {JSX.Element} - 消息气泡组件
 */
const MessageBubble = ({ message }) => {
  // 获取消息内容和发送者信息
  const { text, isUser, timestamp } = message;
  // 获取当前主题信息
  const { activeTheme } = useTheme();
  // 创建引用以访问DOM元素
  const bubbleRef = useRef(null);
  const [copySuccess, setCopySuccess] = useState('');

  /**
   * 复制文本到剪贴板的函数
   * @param {string} text - 要复制的文本
   */
  const copyToClipboard = (text) => {
    navigator.clipboard.writeText(text)
      .then(() => {
        setCopySuccess('已复制');
        setTimeout(() => setCopySuccess(''), 2000);
      })
      .catch(err => {
        console.error('复制失败:', err);
        setCopySuccess('复制失败');
      });
  };

  /**
   * 格式化消息内容，处理代码块和普通文本
   * @param {string} content - 要格式化的消息内容
   * @returns {Array} 格式化后的React元素数组
   */
  const formatMessage = (content) => {
    if (!content || typeof content !== 'string') return '';

    // 分割代码块和普通文本
    const parts = content.split(/(```[\s\S]*?```)/g);
    let key = 0;

    return parts.map((part) => {
      // 处理代码块
      if (part.startsWith('```') && part.endsWith('```')) {
        // 提取语言类型和代码
        const codeContent = part.slice(3, -3);
        const firstLineBreak = codeContent.indexOf('\n');
        
        let language = '';
        let code = codeContent;
        
        // 如果第一行包含语言标识
        if (firstLineBreak > 0) {
          language = codeContent.slice(0, firstLineBreak).trim();
          code = codeContent.slice(firstLineBreak + 1);
        }
        
        return (
          <div className="code-block" key={`code-${key++}`}>
            <div className="code-block-header">
              <span className="code-language">{language || '代码'}</span>
              <button 
                className="copy-button"
                onClick={() => copyToClipboard(code)}
                title="复制代码"
              >
                复制
              </button>
            </div>
            <pre className={`language-${language}`}>
              <code>{code}</code>
            </pre>
          </div>
        );
      } 
      // 处理普通文本
      else {
        // 按行分割
        const lines = part.split('\n');
        
        return (
          <div className="normal-text" key={`text-${key++}`}>
            {lines.map((line, index) => (
              <React.Fragment key={`line-${index}`}>
                {index > 0 && <br />}
                {processLine(line)}
              </React.Fragment>
            ))}
          </div>
        );
      }
    });
  };

  /**
   * 处理单行文本，应用所有可能的格式
   * @param {string} line - 要处理的文本行
   * @returns {Array} 格式化后的React元素数组
   */
  const processLine = (line) => {
    // 首先处理粗体
    const boldFormatted = formatInlineMarkdown(line);
    
    // 然后处理其他格式
    return applyAdditionalFormats(boldFormatted);
  };

  /**
   * 处理内联Markdown格式
   * 支持粗体 (**text** 或 __text__)
   * @param {string} text - 要处理的文本行
   * @returns {Array} 格式化后的React元素数组
   */
  const formatInlineMarkdown = (text) => {
    if (!text || typeof text !== 'string') return '';
    
    // 保存需要渲染的结果片段
    const result = [];
    let lastIndex = 0;
    let currentText = text;
    
    // 处理粗体 (**text** 或 __text__)
    const boldRegex = /(\*\*|__)(.*?)\1/g;
    let match;
    let key = 0;
    
    // 我们将使用正则表达式的exec方法反复匹配所有实例
    while ((match = boldRegex.exec(currentText)) !== null) {
      // 添加匹配前的普通文本
      if (match.index > lastIndex) {
        result.push(currentText.substring(lastIndex, match.index));
      }
      
      // 添加粗体内容
      result.push(<strong key={`bold-${key++}`}>{match[2]}</strong>);
      
      // 更新lastIndex以继续匹配
      lastIndex = match.index + match[0].length;
    }
    
    // 添加剩余的普通文本
    if (lastIndex < currentText.length) {
      result.push(currentText.substring(lastIndex));
    }
    
    // 返回结果，如果没有匹配项，则返回原始文本
    if (result.length === 0) {
      return text;
    }
    
    return result;
  };

  /**
   * 应用额外的格式化
   * 包括斜体和链接
   * @param {string|Array} content - 可能是字符串或由formatInlineMarkdown返回的元素数组
   * @returns {Array} 格式化后的React元素数组
   */
  const applyAdditionalFormats = (content) => {
    // 处理斜体和链接
    if (typeof content === 'string') {
      // 处理斜体 (*text* 或 _text_)
      const italicRegex = /(\*|_)(.*?)\1/g;
      const linkRegex = /\[([^\]]+)\]\(([^)]+)\)/g;
      
      let result = [];
      let lastIndex = 0;
      let currentText = content;
      let key = 0;
      
      // 处理斜体
      let match;
      while ((match = italicRegex.exec(currentText)) !== null) {
        // 添加匹配前的普通文本
        if (match.index > lastIndex) {
          result.push(currentText.substring(lastIndex, match.index));
        }
        
        // 添加斜体内容
        result.push(<em key={`italic-${key++}`}>{match[2]}</em>);
        
        // 更新lastIndex以继续匹配
        lastIndex = match.index + match[0].length;
      }
      
      // 添加剩余的普通文本
      if (lastIndex < currentText.length) {
        result.push(currentText.substring(lastIndex));
      }
      
      // 如果没有斜体匹配，保持原文本
      if (result.length === 0) {
        result = [content];
      }
      
      // 处理链接
      const processLinks = (item) => {
        if (typeof item !== 'string') return item;
        
        const linkResult = [];
        let lastLinkIndex = 0;
        let linkKey = 0;
        let linkMatch;
        
        while ((linkMatch = linkRegex.exec(item)) !== null) {
          // 添加链接前的文本
          if (linkMatch.index > lastLinkIndex) {
            linkResult.push(item.substring(lastLinkIndex, linkMatch.index));
          }
          
          // 添加链接
          linkResult.push(
            <a 
              key={`link-${linkKey++}`}
              href={linkMatch[2]}
              target="_blank"
              rel="noopener noreferrer"
              className="message-link"
            >
              {linkMatch[1]}
            </a>
          );
          
          // 更新lastLinkIndex
          lastLinkIndex = linkMatch.index + linkMatch[0].length;
        }
        
        // 添加剩余文本
        if (lastLinkIndex < item.length) {
          linkResult.push(item.substring(lastLinkIndex));
        }
        
        return linkResult.length > 0 ? linkResult : item;
      };
      
      // 对结果中的每个字符串应用链接处理
      return result.map(item => processLinks(item)).flat();
    } 
    // 如果已经是元素数组，递归处理每个元素
    else if (Array.isArray(content)) {
      return content.map((item, index) => {
        if (typeof item === 'string') {
          return applyAdditionalFormats(item);
        } else if (React.isValidElement(item)) {
          // 递归处理React元素的子元素
          const children = React.Children.toArray(item.props.children);
          const processedChildren = children.map((child, childIndex) => {
            if (typeof child === 'string') {
              return applyAdditionalFormats(child);
            }
            return child;
          });
          
          return React.cloneElement(item, { key: `processed-${index}` }, processedChildren);
        }
        return item;
      }).flat();
    }
    
    return content;
  };

  // 滚动效果：当新消息到达时自动滚动到底部
  useEffect(() => {
    if (bubbleRef.current) {
      // 使用smoothScroll以实现平滑滚动效果
      bubbleRef.current.scrollIntoView({ behavior: 'smooth', block: 'end' });
    }
  }, [text]); // 当消息文本变化时触发

  // 格式化时间戳：将ISO格式的时间戳转换为本地时间
  const formattedTime = () => {
    // 如果没有时间戳或时间戳不是有效的日期格式，返回当前时间
    if (!timestamp || typeof timestamp !== 'string' || isNaN(new Date(timestamp).getTime())) {
      return new Date().toLocaleTimeString([], {
        hour: '2-digit',
        minute: '2-digit'
      });
    }
    
    try {
      return new Date(timestamp).toLocaleTimeString([], {
        hour: '2-digit',
        minute: '2-digit'
      });
    } catch (error) {
      // 如果解析出错，返回当前时间
      console.warn('时间戳格式无效:', timestamp);
      return new Date().toLocaleTimeString([], {
        hour: '2-digit',
        minute: '2-digit'
      });
    }
  };

  return (
    <div 
      ref={bubbleRef}
      className={`message-bubble ${isUser ? 'user-message' : 'bot-message'} ${activeTheme === 'dark' ? 'dark' : 'light'}`}
    >
      {/* 消息内容容器 */}
      <div className="message-content">
        {formatMessage(text)}
      </div>
      
      {/* 时间戳显示 */}
      <div className="message-timestamp">
        {formattedTime()}
      </div>
    </div>
  );
};

export default MessageBubble; 